﻿using System;
using System.Collections.Generic;
using System.Text;

namespace UFrameWork
{
    /// <summary>
    /// 网络心跳包
    /// </summary>
    public class HeartBeat
    {
        /// <summary>
        /// 上次收到的时间
        /// </summary>
        public DateTime PreLastReceiveTime = DateTime.Now;

        /// <summary>
        /// 最后接收到的时间
        /// </summary>
        public DateTime LastReceiveTime = DateTime.Now;

        /// <summary>
        /// 超时时间
        /// </summary>
        public int TimeOut { get; private set; }

        /// <summary>
        /// 心跳消息内容
        /// </summary>
        private const string BeatFlag = "beat";

        /// <summary>
        /// 网络客户端
        /// </summary>
        private USession session;

        /// <summary>
        /// 心跳包数组
        /// </summary>
        private string HeatString;

        /// <summary>
        /// 是否为已超时
        /// </summary>
        /// <returns></returns>
        public bool IsTimeOut()
        {
            return (DateTime.Now - LastReceiveTime).TotalSeconds >= TimeOut;
        }

        /// <summary>
        /// 网络延时
        /// </summary>
        public int Delay
        {
            get
            {
                int d = (int)(LastReceiveTime - PreLastReceiveTime).TotalMilliseconds - 3000;
                return d > 0 ? d : 0;
            }
        }

        /// <summary>
        /// 心跳包管理
        /// </summary>
        /// <param name="timeoute">超时时间</param>
        public HeartBeat(USession client, int timeOut = 20)
        {
            this.session = client;
            TimeOut = timeOut;
            HeatString = BeatFlag + UReceiveFilter.EndFlag;
        }

        /// <summary>
        /// 是否为心跳消息
        /// </summary>
        public bool IsBeatMsg(string msg)
        {
            if ((msg.ToLower() != BeatFlag))
            {
                return false;
            }
            PreLastReceiveTime  = LastReceiveTime;
            LastReceiveTime     = DateTime.Now;
            session.SendString(HeatString);
            return true;
        }
    }
}